import * as THREE from '../../build/three.module.js';
import { OrbitControls } from '../../jsm/controls/OrbitControls.js';
import { GUI } from '../../jsm/libs/dat.gui.module.js';

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x8FBCD4);

scene.add(new THREE.AmbientLight(0x8FBCD4, .4));

const camera = new THREE.PerspectiveCamera(65, innerWidth / innerHeight, 1, 20);
camera.position.z = 8;

const light = new THREE.PointLight(0xffffff, 1);
camera.add(light);
scene.add(camera);

// 创建几何体
const gmt = new THREE.BoxBufferGeometry(2, 2, 2, 32, 32, 32);

gmt.morphAttributes.position = [];

const positions = gmt.attributes.position.array;

const spherePositions = [];
const twisPositions = [];

const direction = new THREE.Vector3(1, 0, 0).normalize();
const vertex = new THREE.Vector3();

for(let i = 0; i < positions.length; i += 3) {
  const x = positions[i];
  const y = positions[i + 1];
  const z = positions[i + 2];

  spherePositions.push(
    x * Math.sqrt(1 - (y * y / 2) - (z * z / 2) + (y * y * z * z / 3)),
    y * Math.sqrt(1 - (z * z / 2) - (x * x / 2) + (z * z * x * x / 3)),
    z * Math.sqrt(1 - (x * x / 2) - (y * y / 2) + (x * x * y * y / 3)),
  )

  vertex.set(x, y, z);

  vertex.applyAxisAngle(direction, Math.PI * x / 2).toArray(twisPositions, twisPositions.length);
}

gmt.morphAttributes.position[0] = new THREE.Float32BufferAttribute(spherePositions, 3);
gmt.morphAttributes.position[1] = new THREE.Float32BufferAttribute(twisPositions, 3);

const mtl = new THREE.MeshPhongMaterial({
  color: 0xff0000,
  flatShading: true,
  morphTargets: true
});

const mesh = new THREE.Mesh(gmt, mtl);
scene.add(mesh);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

new OrbitControls(camera, renderer.domElement);

// 设置 GUI
const params = {
  Spherify: 0,
  Twist: 0
}
const gui = new GUI();
const folder = gui.addFolder('变形目标');

folder.add(params, 'Spherify', 0, 1).step(0.01).onChange((val) => {
  mesh.morphTargetInfluences[0] = val;
})

folder.add(params, 'Twist', 0, 1).step(0.01).onChange((val) => {
  mesh.morphTargetInfluences[1] = val;
})

folder.open();

renderer.setAnimationLoop(() => {

  renderer.render(scene, camera);

});

const handleWindowResize = () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(innerWidth, innerHeight);
}
window.addEventListener('resize', handleWindowResize, false);
